Inheritance in Python
Overview
The object-oriented paradigm places a lot of emphasis/importance on inheritance. Because we can use an existing class to create a new class rather than creating it again from the start, inheritance allows the us to reuse code. With inheritance, the child class access to all the data members, functions, and properties defined in the parent class of that class. A child class may also offer its additional implementation of the parent class's functions. A child/derived class in Python can inherit from its parent/base class by simply putting its name in brackets after the derived class name.
Scope
- In this blog, we will start by learning about basics of classes and objects in Python.
- We will also learn what Inheritance is.
- Then, we will discuss in detail about special functions for Inheritance in Python.
- And finally we will jump into cons and pros of Inheritance.
Introduction
Python is one of the most used programming languages in the world currently. It supports multiple types of programming styles, from the very basic method coding to advance level object-oriented programming. Due to its ease of syntax, python has become a famous/popular choice of language for OOPs.
Inheritance is one of the basic (most used) concepts of OOPs. In this blog, we will look at this robust feature and its various types with practical examples. But before we go into deep, we must get familiar with some important coding concepts like Objects and Classes.
What is Inheritance?
Inheritance is the ability/functionality to ‘inherit’ features/properties or attributes from already written classes into newer classes we create. These features are defined data structures and the functions we can perform with them, as known as Methods. It promotes code reusability, which is considered one of the best industrial/advance coding practices as it makes the codebase modular.
In python inheritance, new class inherits from older class. The new class copies all the older class's functions and attributes without rewriting the code in the new class. This new class is called derived class, and old ones are called base class.
For example, inheritance is often used in biology to symbolize the transfer of genetic attributes from parents to their children. Similar to this, in programming we have parent/base classes and child/derived classes. In Inheritance, we derive class from other already existing class. The existing class are the parent/base class from which the attributes and methods are inherited in the child class.
Types of Inheritance in Python
Now that we are all set with the necessary to understand how inheritance in python is carried out, let’s look at various type of inheritance.
Single Inheritance in Python
This is the simplest/easiest form of inheritance where a single child/derived class is derived from a single parent/base class. Due to its singular nature, it is also known as Simple Inheritance.
# example of single inheritance class parent: # this is parent class def func1(self): print("Hello Parent") class child(parent): # this is child class def func2(self): # we include the parent class print("Hello Child") # as an argument in the child # class # Driver Codetest = child() # object createdtest.func1() # parent method called via child objecttest.func2() # child method called
Output:
> Hello Parent
> Hello Child
Multiple Inheritance in Python
In multiple inheritance, a single child/derived class is inherited from two or more parent/base classes. It means the child/derived class has access to all the parent/base classes' methods and attributes.
However, if two parents/bases have the same “named” methods, the child/derived class performs the method of the first parent/base in order of reference. To better understand which class’s methods shall be executed first, we can use the Method Resolution Order function (MRO). It tells the order in which the child/derived class is interpreted to visit the other classes.
# python 3 syntax# multiple inheritance example class parent1: # first parent class def func1(self): print("Hello Parent1") class parent2: # second parent class def func2(self): print("Hello Parent2") class parent3: # third parent class def func2(self): # the function name is same as parent2 print("Hello Parent3") class child(parent1, parent2, parent3): # child class def func3(self): # we include the parent classes print("Hello Child") # as an argument comma separated # Driver Codetest = child() # object createdtest.func1() # parent1 method called via childtest.func2() # parent2 method called via child instead of parent3test.func3() # child method called # to find the order of classes visited by the child class, we use __mro__ on the child classprint(child.__mro__)
Output:
> Hello Parent1> Hello Parent2> Hello Child>(<class '__main__.child'>, <class '__main__.parent1'>, <class '__main__.parent2'>, <class '__main__.parent3'>,<class 'object'>)
As we can see with the help of MRO, the child/derived class first visits itself, then the first parent/base class, referenced before the second parent/base class. Similarly, it visits the second parent/base class before the third parent/base class, and that’s why it performs the second parent’s function rather than the third parent’s. Finally, it visits any objects that may have been created.
Multilevel Inheritance in Python
In this type of inheritance, we further go beyond just a parent-child relation. We also introduce grandchildren, great-grandchildren, grandparents, etc. We have known only two levels of inheritance with a superior parent class/es and a derived class/es, but here we can have multiple levels where the parent class/es itself is derived from another class/es.
class grandparent: # first level def func1(self): print("Hello Grandparent") class parent(grandparent): # second level def func2(self): print("Hello Parent") class child(parent): # third level def func3(self): print("Hello Child") # Driver Codetest = child() # object createdtest.func1() # 3rd level calls 1st leveltest.func2() # 3rd level calls 2nd leveltest.func3() # 3rd level calls 3rd level
Output
> Hello Grandparent
> Hello Parent> Hello Child
Hierarchical Inheritance in Python
It is the right opposite of multiple inheritance. It means that, there are multiple derived child/derived classes from a single/base parent class.
# python 3 syntax# hierarchical inheritance example class parent: # parent class def func1(self): print("Hello Parent") class child1(parent): # first child class def func2(self): print("Hello Child1") class child2(parent): # second child class def func3(self): print("Hello Child2") # Driver Codetest1 = child1() # objects createdtest2 = child2() test1.func1() # child1 calling parent methodtest1.func2() # child1 calling its own method test2.func1() # child2 calling parent methodtest2.func3() # child2 calling its own method
Output
Hello Parent
> Hello Child1> Hello Parent> Hello Child2
Hybrid Inheritance in Python
Hybrid Inheritance is the mixture/composure of two or more different types of inheritance. Here we can have many relationships between parent/base and child/derived classes with multiple levels.
# python 3 syntax# hybrid inheritance example class parent1: # first parent class def func1(self): print("Hello Parent") class parent2: # second parent class def func2(self): print("Hello Parent") class child1(parent1): # first child class def func3(self): print("Hello Child1") class child2(child1, parent2): # second child class def func4(self): print("Hello Child2") # Driver Codetest1 = child1() # object createdtest2 = child2() test1.func1() # child1 calling parent1 methodtest1.func3() # child1 calling its own method test2.func1() # child2 calling parent1 methodtest2.func2() # child2 calling parent2 methodtest2.func3() # child2 calling child1 methodtest2.func4() # child2 calling its own method
Output:
> Hello Parent1
> Hello Child1> Hello Parent1> Hello Parent2> Hello Child1> Hello Child2
This example shows us a combination of three types of python inheritance.
Parent1 -> Child1 : Single Inheritance
Parent1 -> Child1 -> Child2 : Multi – Level Inheritance
Parent1 -> Child2 <- Parent2 : Multiple Inheritance
The diagrammatic explanation of this hybrid inheritance is:
Special Functions in Python Inheritance
Python is a very versatile/flexible and user-friendly language. It provides many amazing in-built functions that make our lives easier when understanding inheritance or other concepts, especially of a complex nature.
super() function
Method overriding is an ability of any object-oriented programming language that allows a subclass or child/derived class to provide a specific implementation of a method already provided by one of its super-classes or parent/base classes. This discrepancy is caused due to same naming convention of the methods. Commonly we can see this situation when the parent’s init() is overridden by the child’s init(), and hence the child class cannot inherit attributes from the parent class.
Similarly, we can face this same problem with methods other than init but having the same naming methods across parent and child classes.
One solution is to call the parent method inside the child method.
# python 3 syntax# solution to method overriding - 1 class parent: # parent class def __init__(self): # __init__() of parent self.attr1 = 50 self.attr2 = 66 class child(parent): # child class def __init__(self): # __init__() of child parent.__init__(self) # calling parent’s __init__() self.attr3 = 45 test = child() # object initiated print (test.attr1) # parent attribute called via child
Output:
Advantages of Inheritance in Python
- Modular Codebase: Increases modularity, i.e. breaking/dividing down codebase into modules, making it easier to understand. Here, every class we define becomes a separate module that can be inherited separately by one/many classes.
- Code Reusability: the child/derived class copies all the attributes and methods of the parent/base class into its class and use. It saves time and coding effort by not copying them, thus following modularity paradigms.
- Less Development and Maintenance Costs: changes need to be made in the base/Parent class, all derived classes will automatically follow.
Credit: Scaler Topics
Disadvantages of Inheritance in Python
- Decreases the Execution Speed: it decrease the speed by loading multiple classes because they are interdependent.
- Tightly Coupled Classes: this means that even though parent/base classes can be executed independently, child/derived classes cannot be executed without defining their parent classes.
0 Comments